package com.xbongbong.pro.message.service.impl;

import com.alibaba.fastjson.JSON;
import com.xbongbong.message.domain.entity.PushEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.enums.RefEntityEnum;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.message.service.PushLinkService;
import com.xbongbong.pro.message.service.PushService;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * Description: 推送service
 * @author 魏荣杰
 * @date 2019/1/6 1:07
 * @version v1.0
 * @since v1.0
 * Modified by:
 */
@Service("pushService")
public class PushServiceImpl implements PushService {

    private static final String REDIS_WEB_SOCKET_TASK_QUEUE_KEY = "socket-task-queue";

    private static final Logger LOG = LoggerFactory
            .getLogger(PushServiceImpl.class);
    @Resource
    private PushModel pushModel;
    @Resource
    private PushLinkService pushLinkService;
    @Resource
    protected CustomerModel customerModel;
    @Resource
    protected CustomerUserModel customerUserModel;
    @Resource
    protected UserModel userModel;
    @Resource
    protected DepartmentModel departmentModel;
    @Resource
    protected ContractModel contractModel;


    @Override
    public Integer insert(PushEntity entity) throws XbbException {
        Long now = DateTimeUtil.getInt();
        entity.setAddTime(now);
        entity.setUpdateTime(now);

        Integer id = pushModel.insert(entity);
        pushLinkService.insert(entity);
        return id;
    }

    @Override
    public void insertBatch(List<PushEntity> pushList) {
        for (PushEntity push : pushList) {
            checkRefArray(push);
        }
        pushModel.insertBatch(pushList);
        pushLinkService.insertBatch(pushList);
    }

    @Override
    public Integer save(PushEntity pushEntity) throws XbbException {
        String pushObject = pushEntity.getPushObject();
        if (!StringUtil.isEmpty(pushObject)) {
            List<String> userIdList = JSON.parseArray(pushObject, String.class);
            userIdList = new ArrayList<>(new HashSet<>(userIdList));
            pushEntity.setPushObject(JSON.toJSONString(userIdList));
        }
        checkRefArray(pushEntity);

        if (pushEntity.getId() == null || Objects.equals(0L, pushEntity.getId())) {
            return insert(pushEntity);
        }
        return pushModel.update(pushEntity);
    }

    /**
     * 如果消息未设置对象 id 列表则赋初始值
     *
     * @param push 消息
     */
    private void checkRefArray(PushEntity push) {
        if (StringUtil.isEmpty(push.getRefArray())) {
            if (push.getRefId() == null) {
                push.setRefArray("[]");
            } else {
                push.setRefArray("[" + push.getRefId() + "]");
            }
        }
    }



    @Override
    public void immediatelyPush(String corpid, String userId, String title, String content,
                                RefEntityEnum refEntity, Long refId, PushTypeEnum pushType) {
        List<String> userIdList = new ArrayList<>();
        userIdList.add(userId);
        List<Long> refIdList = new ArrayList<>();
        refIdList.add(refId);
        delayedPush(corpid, userIdList, title, content, refEntity, refIdList, pushType, DateUtil.getInt());
    }

    @Override
    public void immediatelyPush(String corpid, List<String> userIdList, String title, String content,
                                RefEntityEnum refEntity, Long refId, PushTypeEnum pushType) {
        List<Long> refIdList = new ArrayList<>();
        refIdList.add(refId);
        delayedPush(corpid, userIdList, title, content, refEntity, refIdList, pushType, DateUtil.getInt());
    }

    @Override
    public void immediatelyPush(String corpid, List<String> userIdList, String title, String content, RefEntityEnum refEntity, Long refId, PushTypeEnum pushType, Map<String, Object> params) {
        List<Long> refIdList = new ArrayList<>();
        refIdList.add(refId);
        delayedPush(corpid, userIdList, title, content, refEntity, refIdList, pushType, DateUtil.getInt(), params);
    }

    @Override
    public void delayedPush(String corpid, String userId, String title, String content, RefEntityEnum refEntity,
                            List<Long> refIdList, PushTypeEnum pushType, Integer pushTime) {
        List<String> userIdList = new ArrayList<>();
        userIdList.add(userId);
        delayedPush(corpid, userIdList, title, content, refEntity, refIdList, pushType, pushTime);
    }

    @Override
    public void delayedPush(String corpid, List<String> userIdList, String title, String content,
                            RefEntityEnum refEntity, Long refId, PushTypeEnum pushType, Integer pushTime) {
        List<Long> refIdList = new ArrayList<>();
        refIdList.add(refId);
        delayedPush(corpid, userIdList, title, content, refEntity, refIdList, pushType, pushTime);
    }

    @Override
    public void delayedPush(String corpid, List<String> userIdList, String title, String content, RefEntityEnum refEntity, Long refId, PushTypeEnum pushType, Integer pushTime, Map<String, Object> params) {
        List<Long> refIdList = new ArrayList<>();
        refIdList.add(refId);
        delayedPush(corpid, userIdList, title, content, refEntity, refIdList, pushType, pushTime, params);
    }

    @Override
    public void immediatelyPush(String corpid, List<String> userIdList, String title, String content,
                                RefEntityEnum refEntity, List<Long> refIdList, PushTypeEnum pushType) {
        delayedPush(corpid, userIdList, title, content, refEntity, refIdList, pushType, DateUtil.getInt());
    }

    @Override
    public void delayedPush(String corpid, List<String> userIdList, String title, String content,
                            RefEntityEnum refEntity, List<Long> refIdList, PushTypeEnum pushType, Integer pushTime) {
        delayedPush(corpid, userIdList, title, content, refEntity, refIdList, pushType, pushTime, null);
    }

    @Override
    public void delayedPush(final String corpid, final List<String> userIdList, final String title, final String content,
                            final RefEntityEnum refEntity, final List<Long> refIdList, final PushTypeEnum pushType,
                            final Integer pushTime, final Map<String, Object> params) {
        delayedPush(corpid, userIdList, title, content, refEntity, refIdList, pushType, "", pushTime, params);
    }

    @Override
    public void delayedPush(final String corpid, final List<String> userIdList, final String title, final String content,
                            final RefEntityEnum refEntity, final List<Long> refIdList, final PushTypeEnum pushType,
                            final String attrEntity, final Integer pushTime, final Map<String, Object> params) {
        Runnable messageTask = new Runnable() {
            @Override
            public void run() {
                //TODO message 核心推送
   /*             if (userIdList == null || userIdList.size() == 0) {
                    // 无接收消息用户，直接返回
                    return;
                }
                if (refIdList == null || refIdList.size() == 0) {
                    // 无消息对应的对象
                    return;
                }
                PushEntity push = new PushEntity();
                if(!StringUtil.isEmpty(attrEntity)){
                    push.setAttrEntity(attrEntity);
                }
                push.setCorpid(corpid);
                push.setIsPush(0);
                push.setPushObject(JSONObject.toJSONString(userIdList));
                push.setPushTime(pushTime);
                Integer refId = refIdList.get(0);
                push.setRefId(refId);
                push.setRefEntity(refEntity.getCode());
                JSONObject msgJSON = new JSONObject();
                msgJSON.put("title", title == null ? "销帮帮CRM" : title);
                msgJSON.put("content", content == null ? "" : content);
                if (params != null) {
                    msgJSON.putAll(params);
                }
                String messageUrl = ConfigConstant.appUrl;
                String pcMessageUrl = ConfigConstant.webUrl;
                switch (pushType) {
                    case CUSTOMER_PUSH:
                    case CUSTOMER_ADD_PUSH:
                    case CUSTOMER_CHANGE_PUSH:
                    case CUSTOMER_HANDOVER_PUSH:
                    case CUSTOMER_DISTRIBUTION_PUSH:
                    case CUSTOMER_STAGE:
                    case CUSTOMER_BACK_PUBLIC:
                    case CUSTOMER_TEAM_ADD_DEL_MAIN:
                    case CUSTOMER_TEAM_ADD_DEL_SYNERGETIC:
                    case CUSTOMER_BACK_PUSH:
                    case CUSTOMER_WILL_BACK_PUSH:
                        messageUrl += String.format(DingtalkPageUrlEnum.CUSTOMER_DETAIL.getUrl(), refId);
                        break;
                    case OPPORTUNITY_PUSH:
                    case OPPORTUNITY_ADD_PUSH:
                    case OPPORTUNITY_CHANGE_PUSH:
                    case OPPORTUNITY_EXPIRE_PUSH:
                    case OPPORTUNITY_TEAM_ADD_DEL_MAIN_PUSH:
                    case OPPORTUNITY_TEAM_ADD_DEL_SYNERGETIC_PUSH:
                        messageUrl += String.format(DingtalkPageUrlEnum.OPPORTUNITY_DETAIL.getUrl(), refId);
                        break;
                    case CONTRACT_PUSH:
                    case CONTRACT_ADD_PUSH:
                    case CONTRACT_CHANGE_PUSH:
                    case CONTRACT_TEAM_ADD_DEL_MAIN_PUSH:
                    case CONTRACT_TEAM_ADD_DEL_SYNERGETIC_PUSH:
                        messageUrl += String.format(DingtalkPageUrlEnum.CONTRACT_DETAIL.getUrl(), refId);
                        break;
                    case CONTACT_PUSH:
                    case CONTACT_NEW:
                        messageUrl += String.format(DingtalkPageUrlEnum.CONTACT_DETAIL.getUrl(), refId);
                        break;
                    case COMMUNICATE_PUSH:
                    case COMMUNICATE_ADD_PUSH:
                    case COMMUNICATE_LIKE_PUSH:
                    case COMMUNICATE_COMMENT_PUSH:
                    case COMMUNICATE_REPLY_PUSH:
                    case COMMUNICATE_AT_PUSH:
                        messageUrl += String.format(DingtalkPageUrlEnum.COMMUNICATE_DETAIL.getUrl(), refId);
                        break;
                    case COMMUNICATE_ADD_PUSH_SUPPLIER:
                    case COMMUNICATE_LIKE_PUSH_SUPPLIER:
                    case COMMUNICATE_COMMENT_PUSH_SUPPLIER:
                    case COMMUNICATE_REPLY_PUSH_SUPPLIER:
                        messageUrl += String.format(DingtalkPageUrlEnum.SUPPLIER_DETAIL.getUrl(), refId);
                        break;
                    case COMMUNICATE_ADD_PUSH_PURCHASE:
                    case COMMUNICATE_LIKE_PUSH_PURCHASE:
                    case COMMUNICATE_COMMENT_PUSH_PURCHASE:
                    case COMMUNICATE_REPLY_PUSH_PURCHASE:
                        messageUrl += String.format(DingtalkPageUrlEnum.PURCHASE_DETAIL.getUrl(), refId);
                        break;
                    case COMMUNICATE_PLAN_ADD_PUSH:
                    case COMMUNICATE_PLAN_REMIND:
                        messageUrl += String.format(DingtalkPageUrlEnum.COMMUNICATE_PLAN_DETAIL.getUrl(), refId);
                        break;
                    case APPROVAL_PUSH:
                    case APPROVAL_ADD_PUSH:
                    case APPROVAL_CHANGE_PUSH:
                    case APPROVAL_NODE_CHANGE_PUSH:
                    case APPROVAL_AGREE_PUSH:
                    case APPROVAL_REFUSE_PUSH:
                    case APPROVAL_REEDIT_PUSH:
                        messageUrl += String.format(DingtalkPageUrlEnum.APPROVAL_DETAIL.getUrl(),refId);
                        break;
                    case WORK_REPORT_PUSH:
                    case WORK_REPORT_ADD_PUSH:
                    case WORK_REPORT_COMMENT_PUSH:
                    case WORK_REPORT_COMMENT_LIKE_PUSH:
                    case WORK_REPORT_AT_PUSH:
                        messageUrl += String.format(DingtalkPageUrlEnum.WORK_REPORT_DETAIL.getUrl(), refId);
                        break;
                    case SALE_REPORT_PUSH:
                        // 销售简报消息推送---------------简报的一些信息在外部塞入了一个dataJson，此处把dataJson置入msgJSON内
                        Integer start = (params == null) ? null : (Integer) params.get("start");
                        Integer end = (params == null) ? null : (Integer) params.get("end");
                        messageUrl += "/reportTargetApi/index.html?to=app&start=" + start + "&end=" + end + "&dd_nav_bgcolor=ffff943e";
                        pcMessageUrl = ConfigConstant.appUrl + "/reportTargetApi/index.html?to=web&start=" + start + "&end=" + end + "&dd_nav_bgcolor=ffff943e";
                        break;
                    case WORKORDER_PUSH:
                    case WORKORDER_NEW_EXECUTOR:
                    case WORKORDER_NEW_EXECUTED:
                    case WORKORDER_CONFIRM:
                    case WORKORDER_TEAM:
                    case WORKORDER_STAGE_COMPLETE:
                    case WORKORDER_COMPLETE:
                    case WORKORDER_CLOSE:
                    case WORKORDER_RESTART:
                    case WORKORDER_TRANSFER:
                    case WORKORDER_ROLLBACK:
                        //工单
                        messageUrl += String.format(DingtalkPageUrlEnum.WORK_ORDER_DETAIL.getUrl(), refId);
                        break;
                    case WORKORDER_DEL_PUSH:
                        //工单删除
                        messageUrl = DINGTALK_INDEX_PAGE_URL;
                        break;
                    case WORKORDER_DYNAMIC_PUSH:
                        //工单动态
                        messageUrl += String.format(DingtalkPageUrlEnum.WORK_ORDER_DYNAMIC.getUrl(), refId);
                        break;
                    case EXPIRED_PUSH:
                        // 套餐到期推送
                        messageUrl += DingtalkPageUrlEnum.EXPIRED.getUrl();
                        break;
                    case WAIT_PURCHASE_PUSH:
                        //待采购列表
                        messageUrl += DingtalkPageUrlEnum.WAIT_PURCHASE_LIST.getUrl();
                        break;
                    case WAIT_OUTSTOCK_PUSH:
                        //待出库列表
                        messageUrl += DingtalkPageUrlEnum.WAIT_OUTSTOCK_LIST.getUrl();
                        break;
                    case WAIT_INSTOCK_PUSH:
                        //待入库列表
                        messageUrl += DingtalkPageUrlEnum.WAIT_INSTOCK_LIST.getUrl();
                        break;
                    case PURCHASE_PUSH:
                        //采购提醒
                        messageUrl += String.format(DingtalkPageUrlEnum.PURCHASE_DETAIL.getUrl(), refId);
                        break;
                    case INSTOCK_PUSH:
                        //采购入库提醒
                        messageUrl += String.format(DingtalkPageUrlEnum.INSTOCK_DETAIL.getUrl(), refId);
                        break;
                    case OUTSTOCK_PUSH:
                        //销售出库提醒
                        messageUrl += String.format(DingtalkPageUrlEnum.CONTRACT_DETAIL.getUrl(), refId);
                        break;
                    case SUPPLIER_PUSH:
                        //供应商提醒
                        messageUrl += String.format(DingtalkPageUrlEnum.SUPPLIER_DETAIL.getUrl(), refId);
                        break;
                    case EXPORT_PUSH:
                        if(params!=null && params.get("downLoadUrl")!=null) {
                            messageUrl = params.get("downLoadUrl").toString();
                        }
                        break;
                    case PAYMENT_PLAN_ADD:
                    case PAYMENT_SHEET_ADD:
                    case PAYMENT_SHEET_RED_ADD:
                    case PAYMENT_SHEET_BAD_ADD:
                        messageUrl+= String.format(DingtalkPageUrlEnum.PAYMENT_DETAIL.getUrl(), refId);
                        break;
                    case PAYMENT_REMIND:
                    case PAYMENT_OVERDUE:
                        messageUrl += String.format(DingtalkPageUrlEnum.PAYMENT_LIST.getUrl(), "");
                        break;
                    case INVOICE_PUSH:
                    case INVOICE_ADD_PUSH:
                    case INVOICE_RED_ADD_PUSH:
                    case INVOICE_DEL_PUSH:
                    case INVOICE_REDUCTION:
                    case INVOICE_INVALIDATION:
                        messageUrl += String.format(DingtalkPageUrlEnum.INVOICE_DETAIL.getUrl(), refId);
                        break;
                    case SIGN_IN_ADD_PUSH:
                        messageUrl += String.format(DingtalkPageUrlEnum.CUSTOMER_DETAIL.getUrl(), refId);
                        break;
                    case BOMBILL_PUSH:
                        //BOM清单推送
                        messageUrl += String.format(DingtalkPageUrlEnum.BOM_BILL_DETAIL.getUrl(), refId);
                        break;
                    case PRODUCTION_ORDER_PUSH:
                        //生产单推送
                        messageUrl += String.format(DingtalkPageUrlEnum.PRODUCTION_ORDER_DETAIL.getUrl(), refId);
                        break;
                    default:
                        messageUrl = DINGTALK_INDEX_PAGE_URL;
                        break;
                }

                if (StringUtil.isEmpty(messageUrl)) {
                    messageUrl = DINGTALK_INDEX_PAGE_URL;
                }
                //dingtalk 所需参数
                String otherParam = "&ov=y&corpid=" + corpid + "&appid=" + Env.DING_XBB_APP_ID;
                if(!PushTypeEnum.EXPORT_PUSH.equals(pushType)) {
                    messageUrl += otherParam;
                }
                msgJSON.put("messageUrl", messageUrl);
                if (pcMessageUrl != null) {
                    if(!PushTypeEnum.EXPORT_PUSH.equals(pushType)) {
                        pcMessageUrl += otherParam;
                    }
                    msgJSON.put("pcMessageUrl", pcMessageUrl);
                }

                String msg = JSON.toJSONString(msgJSON);
                push.setRefArray(JSON.toJSONString(refIdList));
                push.setMsg(msg);
                push.setSubType(pushType.getSubCode());
                push.setType(pushType.getCode());

                save(push);
*/
            }
        };
//            ThreadPoolHelper.getInstance().submitExecutorRunnable(messageThreadPool, messageTask);
    }



}
